HAL FMC SRAM initialization and configuration functions migration ¶
The goal of this page is to show how to migrate the initialization sequence using STM32CubeMX2:
Open STM32CubeMX2 FMC SRAM configuration panel.
Configure the SW layer HAL.
Configure the FMC SRAM main features.
Configure the FMC SRAM advanced features.
Configure the FMC SRAM security and privilege features if needed.
Configure the FMC SRAM GPIO pins.
Generate the code.
Note
There is four configurations that can be done in HAL FMC SRAM:
Asynchronous memory
HAL_SRAM_SetConfigRdWrAsyncMemory(), with an optional configuration to set different timings for write operations when needed usingHAL_SRAM_SetWrAsyncTimings().Synchronous memory
HAL_SRAM_SetConfigRdWrSyncMemory().Synchronous/Asynchronous memory
HAL_SRAM_SetConfigRdSyncWrAsyncMemory().Asynchronous/Synchronous memory
HAL_SRAM_SetConfigRdAsyncWrSyncMemory().
The instance have been changed from bank in HAL1 to sub-bank in HAL2.
HAL FMC SRAM configuration panel ¶
Create a new project with STM32CubeMX2, start by enabling the FMC instance as SRAM/PSRAM, as shown in this example with the selected FMC-NOR_PSRAM1, then start the initialization and the main configuration.
HAL FMC SRAM main features configuration ¶
Configure the FMC SRAM main features.
HAL FMC SRAM advanced features configuration ¶
Configure the advanced FMC SRAM features.
HAL FMC SRAM security and privilege features configuration ¶
Configure the FMC SRAM security and privilege features if needed.
GPIO configuration ¶
Configure GPIO pins.
Generated SRAM initialization and de-initialization sequences ¶
The FMC SRAM initialization and de-initialization sequences are generated in the
mx_fmc_nor_psram1_sram_init
function in
mx_fmc.c
file under
$YOUR_PROJECT_NAME$/$YOUR_PROJECT_NAME$_SW/generated/STM32Cube_CodeGen.
Related concepts:
Note
Example: This configuration is reserved to STM32U5 (Specific Pins)
|
Topic |
HAL1 code snippet |
HAL2 code snippet |
|---|---|---|
|
Handle declaration |
SRAM_HandleTypeDef hsram1;
GPIO_InitTypeDef GPIO_InitStruct ={0};
|
hal_sram_handle_t hNOR_PSRAM1;
hal_sram_config_t sram_config;
hal_sram_rd_wr_async_memory_config_t p_config;
hal_gpio_config_t gpio_config;
|
|
Initialization and configuration sequence |
/* FMC initialization function */
static void MX_FMC_Init(void)
{
FMC_NORSRAM_TimingTypeDef Timing = {0};
/** Perform the SRAM1 memory initialization sequence
*/
hsram1.Instance = FMC_NORSRAM_DEVICE;
hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
hsram1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_8;
hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_ENABLE;
hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
hsram1.Init.WriteFifo = FMC_WRITE_FIFO_DISABLE;
hsram1.Init.NBLSetupTime = 0;
hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
hsram1.Init.MaxChipSelectPulse = DISABLE;
/* Timing */
Timing.AddressSetupTime = 3;
Timing.AddressHoldTime = 1;
Timing.DataSetupTime = 3;
Timing.DataHoldTime = 1;
Timing.BusTurnAroundDuration = 1;
Timing.CLKDivision = 2;
Timing.DataLatency = 2;
Timing.AccessMode = FMC_ACCESS_MODE_A;
/* ExtTiming */
if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
{
Error_Handler( );
}
}
static void HAL_FMC_MspInit(void){
if (FMC_Initialized) {
return;
}
FMC_Initialized = 1;
__HAL_RCC_FMC_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_3 | GPIO_PIN_6 | GPIO_PIN_10 | GPIO_PIN_9 | \
GPIO_PIN_8 | GPIO_PIN_14 | GPIO_PIN_7 | GPIO_PIN_13 | GPIO_PIN_11 |GPIO_PIN_15 | GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_0 | GPIO_PIN_4|GPIO_PIN_7 | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_1 | \
GPIO_PIN_14 | GPIO_PIN_15 | GPIO_PIN_12 | GPIO_PIN_10 | GPIO_PIN_13 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_5 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_12 | \
GPIO_PIN_14 |GPIO_PIN_13 | GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_0 | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
}
void HAL_SRAM_MspInit(SRAM_HandleTypeDef* hsram)
{
HAL_FMC_MspInit();
}
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
}
|
hal_sram_handle_t *mx_fmc_nor_psram1_sram_init(void)
{
if (HAL_SRAM_Init(&hNOR_PSRAM1, HAL_SRAM1) != HAL_OK)
{
return NULL;
}
HAL_RCC_FMC_EnableClock();
sram_config.memory_type = HAL_SRAM_MEMORY_TYPE_SRAM;
sram_config.wait_signal_polarity = HAL_SRAM_WAIT_SIGNAL_POLARITY_LOW;
if (HAL_SRAM_SetConfig(&hNOR_PSRAM1, &sram_config) != HAL_OK)
{
return NULL;
}
/* Asynchronous read and write with identical timing for both operation */
p_config.memory.data_bus_width = HAL_SRAM_DATA_BUS_WIDTH_8_BIT;
p_config.memory.cram_page_size_byte = HAL_SRAM_CRAM_PAGE_SIZE_NONE;
p_config.memory.mux_data_addr = HAL_SRAM_MUX_DATA_ADDR_DISABLE;
p_config.memory.byte_lane_setup_cycle = HAL_SRAM_BYTE_LANE_SRC_CLK_0_CYCLE;
p_config.memory.psram_chipsel_maxpulse_nsec = 20;
p_config.timings.async_access_timings.addr_setup_nsec = 10;
p_config.timings.async_access_timings.addr_hold_nsec = 20;
p_config.timings.async_access_timings.data_setup_nsec = 20;
p_config.timings.async_access_timings.data_hold_nsec = 10;
p_config.timings.async_wait = HAL_SRAM_ASYNC_WAIT_SIGNAL_DISABLE;
p_config.timings.bus_turnaround_nsec = 10;
if (HAL_SRAM_SetConfigRdWrAsyncMemory(&hNOR_PSRAM1, &p_config) != HAL_OK)
{
return NULL;
}
HAL_SRAM_EnableMemory(&hNOR_PSRAM1);
HAL_RCC_GPIOC_EnableClock();
HAL_RCC_GPIOD_EnableClock();
HAL_RCC_GPIOA_EnableClock();
HAL_RCC_GPIOB_EnableClock();
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_12;
HAL_GPIO_Init(HAL_GPIOC, HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_3 | \
HAL_GPIO_PIN_4 | HAL_GPIO_PIN_5, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_12;
HAL_GPIO_Init(HAL_GPIOD, HAL_GPIO_PIN_12, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_10;
HAL_GPIO_Init(HAL_GPIOD, HAL_GPIO_PIN_8 | HAL_GPIO_PIN_9, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_12;
HAL_GPIO_Init(HAL_GPIOA, HAL_GPIO_PIN_12 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_10 | \
HAL_GPIO_PIN_9 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_0 | HAL_GPIO_PIN_5, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_10;
HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_0, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_7;
HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_1, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_12;
HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_2, &gpio_config);
return &hNOR_PSRAM1;
}
|
|
Deinitialization sequence |
static void HAL_FMC_MspDeInit(void)
{
if (FMC_DeInitialized) {
return;
}
FMC_DeInitialized = 1;
/* Peripheral clock enable */
__HAL_RCC_FMC_CLK_DISABLE();
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_7 | GPIO_PIN_8 | \
GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |GPIO_PIN_14 | GPIO_PIN_15);
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | \
GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | \
GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
HAL_GPIO_DeInit(GPIOG, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_12);
}
void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef* hsram)
{
HAL_FMC_MspDeInit();
}
static void MX_FMC_DeInit(void)
{
/* Deinitialize the SRAM peripheral */
if (HAL_SRAM_DeInit(&hsram1) != HAL_OK)
{
Error_Handler();
}
}
|
void mx_fmc_nor_psram1_sram_deinit(void)
{
/* De-initialize all GPIO pins associated with FMC */
HAL_GPIO_DeInit(HAL_GPIOC, HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_3 | HAL_GPIO_PIN_4 | HAL_GPIO_PIN_5);
HAL_GPIO_DeInit(HAL_GPIOD, HAL_GPIO_PIN_8 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_12);
HAL_GPIO_DeInit(HAL_GPIOA, HAL_GPIO_PIN_0 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | \
HAL_GPIO_PIN_5 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_10 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_12);
HAL_GPIO_DeInit(HAL_GPIOB, HAL_GPIO_PIN_0 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2);
HAL_SRAM_DeInit(&hNOR_PSRAM1);
}
|
All subbanks configuration ¶
|
HAL1 code snippet |
HAL2 code snippet |
|---|---|
SRAM_HandleTypeDef hsram[4] = {hsram1, hsram2, hsram3, hsram4};
uint32_t sram_instance[4] = {FMC_NORSRAM_BANK1, FMC_NORSRAM_BANK2, FMC_NORSRAM_BANK3, FMC_NORSRAM_BANK4};
HAL_Init();
// --- SRAM bank (1) and sub-banks Initialization SRAMx (x = 1 to 4) ---
for (int i = 0; i < 4; i++)
{
hsram[i].Instance = FMC_NORSRAM_DEVICE;
hsram[i].Extended = FMC_NORSRAM_EXTENDED_DEVICE;
hsram[i].Init.NSBank = sram_instance[i];
hsram[i].Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
hsram[i].Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
hsram[i].Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
hsram[i].Init.WrapMode = FMC_WRAP_MODE_DISABLE;
hsram[i].Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
hsram[i].Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
hsram[i].Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
hsram[i].Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
hsram[i].Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
// Fill static configuration
hsram[i].Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
/* ---------------------------------------------------------- */
hsram[i].Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
// Fill memory configuration
hsram[i].Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
hsram[i].Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
Sram_Timing.AddressSetupTime = 2;
Sram_Timing.AddressHoldTime = 1;
Sram_Timing.DataSetupTime = 2;
Sram_Timing.DataHoldTime = 1;
Sram_Timing.BusTurnAroundDuration = 1;
Sram_Timing.CLKDivision = 2;
Sram_Timing.DataLatency = 2;
/* Optional: Set different write timings if needed */
Sram_Wr_Timing.AddressSetupTime = 3;
Sram_Wr_Timing.AddressHoldTime = 1;
Sram_Wr_Timing.DataSetupTime = 3;
Sram_Wr_Timing.DataHoldTime = 1;
Sram_Wr_Timing.BusTurnAroundDuration = 1;
Sram_Wr_Timing.AccessMode = FMC_ACCESS_MODE_A;
HAL_SRAM_Init(&hsram[i], &Sram_Timing, &Sram_Wr_Timing);
}
|
hal_sram_handle_t* hsram [4] ={hsram1, hsram2, hsram3, hsram4};
hal_sram_t sram_instance[4] = {HAL_SRAM1, HAL_SRAM2, HAL_SRAM3, HAL_SRAM4};
HAL_Init();
// Initialize the SRAM handle and associate to the HAL_SRAMx instance
for (int i = 0; i < 4; i++)
{
HAL_SRAM_Init(&hsram[i], sram_instance[i]);
}
// Fill static configuration of FMC peripheral
sram_config.memory_type = HAL_SRAM_MEMORY_TYPE_SRAM;
sram_config.write_fifo = HAL_SRAM_WRITE_FIFO_DISABLE;
sram_config.wait_signal_polarity = HAL_SRAM_WAIT_SIGNAL_POLARITY_LOW;
/* Fill memory configuration */
sram_mem_config.memory.data_width = HAL_SRAM_DATA_BUS_WIDTH_16_BIT;
sram_mem_config.memory.cram_page_size_byte = HAL_SRAM_PAGE_SIZE_NONE;
sram_mem_config.memory.mux_mode = HAL_SRAM_MUX_DATA_ADDR_DISABLE;
sram_mem_config.memory.byte_lane_setup_cycle = HAL_SRAM_BYTE_LANE_SRC_CLK_0_CYCLE;
sram_mem_config.memory.psram_chipsel_maxpulse_nsec = 0;
sram_mem_config.timings.async_wait = HAL_SRAM_ASYNC_WAIT_SIGNAL_DISABLE;
sram_mem_config.timings.async_access_timings.addr_setup_nsec = 20;
sram_mem_config.timings.async_access_timings.addr_hold_nsec = 10;
sram_mem_config.timings.async_access_timings.data_setup_nsec = 20;
sram_mem_config.timings.async_access_timings.data_hold_nsec = 10;
sram_mem_config.timings.bus_turnaround_nsec = 10;
/* ---------------------------------------------------------- */
/* ---------------------------------------------------------- */
/* Optional: Set different write timings if needed */
sram_wr_timings.async_access_timings.addr_setup_nsec = 30;
sram_wr_timings.async_access_timings.addr_hold_nsec = 10;
sram_wr_timings.async_access_timings.data_setup_nsec = 30;
sram_wr_timings.async_access_timings.data_hold_nsec = 10;
sram_wr_timings.bus_turnaround_nsec = 10;
sram_wr_timings.read_access_mode = HAL_SRAM_ACCESS_MODE_A;
sram_wr_timings.write_access_mode = HAL_SRAM_ACCESS_MODE_A;
for (int i = 0; i < 4; i++)
{
HAL_SRAM_SetConfig(&hsram[i], &sram_config); // FMC peripheral configuration
HAL_SRAM_SetConfigRdWrAsyncMemory(&hsram[i], &sram_mem_config); // FMC memory configuration
HAL_SRAM_SetWrAsyncTimings(&hsram[i], &sram_wr_timings); //Optional: FMC write timing configuration when different timing needed for write operation
HAL_SRAM_EnableMemory(&hsram[i]); // Enable the SRAM sub-bank x
}
|